package com.csu.common.utils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.log4j.Logger;

public class HttpUtil
{

    private static Logger LogUtil = Logger.getLogger(HttpUtil.class);

    private static int DEFAULT_TIMEOUT = 30000;
    // 对于局域网服务器请求必须在2秒内响应，否则不继续等待
    public static int DEFAULT_TIMEOUT_MIN = 2000;

    public static String postMap(String url, Map<String, Object> params)
    {
        // 构建请求参数
        String paramStr = getParamStr(params);
        return post(url, paramStr);
    }

    public static String postMapQuick(String url, Map<String, Object> params)
    {
        // 构建请求参数
        String paramStr = getParamStr(params);
        return post(url, paramStr, DEFAULT_TIMEOUT_MIN);
    }

    public static String post(String url, String param)
    {
        return post(url, param, DEFAULT_TIMEOUT);
    }

    public static String post(String url, String param, int timeOutMilliSeconds)
    {
        // 读取返回内容
        StringBuilder buffer = new StringBuilder();
        // 构建请求参数
        String paramStr = param;
        LogUtil.info("send_url:" + url);
        LogUtil.info("send_data:" + paramStr);

        URL u = null;
        HttpURLConnection con = null;
        OutputStreamWriter osw = null;
        InputStream in = null;
        InputStreamReader isr = null;
        BufferedReader br = null;

        // 尝试发送请求
        try
        {
            // 设置此类是否应该自动执行 HTTP 重定向（响应代码为 3xx 的请求）。
            HttpURLConnection.setFollowRedirects(true);
            u = new URL(url);
            con = (HttpURLConnection) u.openConnection();

            // // POST 只能为大写，严格限制，post会不识别
            con.setRequestMethod("POST");
            con.setConnectTimeout(timeOutMilliSeconds);
            con.setDoOutput(true);
            con.setDoInput(true);
            con.setUseCaches(false);
            con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            osw = new OutputStreamWriter(con.getOutputStream(), "UTF-8");
            if (paramStr != null)
            {
                osw.write(paramStr);
                osw.flush();
            }
            if (con.getResponseCode() == HttpURLConnection.HTTP_OK)
            {
                in = con.getInputStream();
                isr = new InputStreamReader(in, "UTF-8");
                br = new BufferedReader(isr);
                String line = br.readLine();
                while (line != null)
                {
                    buffer.append(line);
                    line = br.readLine();
                }
            }
            else
            {
                LogUtil.warn("post failed.code:" + con.getResponseCode() + "url:" + url + ",param:" + paramStr);
            }
        }
        catch (Exception e)
        {
            LogUtil.error("http请求出错.url:" + url + ",param:" + paramStr, e);
        }
        finally
        {
            if (null != osw)
            {
                try
                {
                    osw.close();
                }
                catch (IOException e)
                {
                    LogUtil.error("http请求,关闭OutputStreamWriter出错.url:" + url + ",param:" + paramStr, e);
                }
            }
            if (null != br)
            {
                try
                {
                    br.close();
                }
                catch (IOException e)
                {
                    LogUtil.error("http请求,关闭BufferedReader出错.url:" + url + ",param:" + paramStr, e);
                }
            }
            if (null != isr)
            {
                try
                {
                    isr.close();
                }
                catch (IOException e)
                {
                    LogUtil.error("http请求,关闭InputStream出错.url:" + url + ",param:" + paramStr, e);
                }
            }
            if (null != in)
            {
                try
                {
                    in.close();
                }
                catch (IOException e)
                {
                    LogUtil.error("http请求,关闭InputStreamReader出错.url:" + url + ",param:" + paramStr, e);
                }
            }
            if (con != null)
            {
                con.disconnect();
            }
        }

        return buffer.toString();
    }

    public static String getMap(String url, Map<String, Object> params)
    {
        // 构建请求参数
        String paramStr = getParamStr(params);
        return get(url, paramStr);
    }

    public static String getMapQuick(String url, Map<String, Object> params)
    {
        // 构建请求参数
        String paramStr = getParamStr(params);
        return get(url, paramStr, DEFAULT_TIMEOUT_MIN);
    }

    public static String get(String url, String param)
    {
        return get(url, param, DEFAULT_TIMEOUT);
    }

    public static String get(String url, String param, int timeOutMilliSeconds)
    {
        // 读取返回内容
        StringBuilder buffer = new StringBuilder();
        // 构建请求参数
        if (param != null)
        {
            url = url + "?" + param;
        }
        LogUtil.info("get_url:" + url);

        URL u = null;
        HttpURLConnection con = null;
        OutputStreamWriter osw = null;
        InputStream in = null;
        InputStreamReader isr = null;
        BufferedReader br = null;

        // 尝试发送请求
        try
        {
            // 设置此类是否应该自动执行 HTTP 重定向（响应代码为 3xx 的请求）。
            HttpURLConnection.setFollowRedirects(true);
            u = new URL(url);
            con = (HttpURLConnection) u.openConnection();

            // // POST 只能为大写，严格限制，post会不识别
            con.setRequestMethod("GET");
            con.setConnectTimeout(timeOutMilliSeconds);
            con.setUseCaches(false);
            if (con.getResponseCode() == HttpURLConnection.HTTP_OK)
            {
                in = con.getInputStream();
                isr = new InputStreamReader(in, "UTF-8");
                br = new BufferedReader(isr);
                String line = br.readLine();
                while (line != null)
                {
                    buffer.append(line);
                    line = br.readLine();
                }
            }
            else
            {
                LogUtil.warn("get failed.code:" + con.getResponseCode() + "url:" + url);
            }
        }
        catch (Exception e)
        {
            LogUtil.error("http请求出错.url:" + url, e);
        }
        finally
        {
            if (null != osw)
            {
                try
                {
                    osw.close();
                }
                catch (IOException e)
                {
                    LogUtil.error("http请求,关闭OutputStreamWriter出错.url:" + url, e);
                }
            }
            if (null != br)
            {
                try
                {
                    br.close();
                }
                catch (IOException e)
                {
                    LogUtil.error("http请求,关闭BufferedReader出错.url:" + url, e);
                }
            }
            if (null != isr)
            {
                try
                {
                    isr.close();
                }
                catch (IOException e)
                {
                    LogUtil.error("http请求,关闭InputStream出错.url:" + url, e);
                }
            }
            if (null != in)
            {
                try
                {
                    in.close();
                }
                catch (IOException e)
                {
                    LogUtil.error("http请求,关闭InputStreamReader出错.url:" + url, e);
                }
            }
            if (con != null)
            {
                con.disconnect();
            }
        }

        return buffer.toString();
    }

    private static String getParamStr(Map<String, Object> params)
    {
        String rs = "";
        // 构建请求参数
        StringBuilder sb = new StringBuilder();
        if (params != null)
        {
            for (Entry<String, Object> e : params.entrySet())
            {
                sb.append(e.getKey());
                sb.append("=");
                sb.append(e.getValue());
                sb.append("&");
            }
            rs = sb.substring(0, sb.length() - 1);
        }
        return rs;
    }

    /**
     * 
     * @param url
     * @return Utf8编码的url
     * @author chenshen
     */
    public static String utf8URLencode(String url)
    {
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < url.length(); i++)
        {
            char c = url.charAt(i);
            if (c >= 0 && c <= 255)
            {
                result.append(c);
            }
            else
            {
                byte[] b = new byte[0];
                try
                {
                    b = Character.toString(c).getBytes("UTF-8");
                }
                catch (Exception ex)
                {
                    LogUtil.error(ex.getMessage());
                }
                for (int j = 0; j < b.length; j++)
                {

                    int k = b[j];
                    if (k < 0)
                    {
                        k += 256;
                    }
                    result.append("%" + Integer.toHexString(k).toUpperCase());
                }
            }
        }
        return result.toString().replaceAll(" ", "%20");
    }
}
